package com.common.data.desensitization.common.controller;

import com.common.data.desensitization.common.annotation.DesensitizationRule;
import com.common.data.desensitization.common.annotation.Desensitize;
import com.common.data.desensitization.common.enums.DesensitizationStrategyEnum;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @ClassName DataController
 * @Description TODO
 * @Author 86152
 * @Date 2025/5/18 13:19
 * @Version 1.0
 **/
@RestController
public class DataController {
    @GetMapping("/user/{id}")
    @Desensitize(rules = {
            @DesensitizationRule(jsonPath = "$.name", strategy = DesensitizationStrategyEnum.PREFIX_KEEP, prefixKeep = 1),
            @DesensitizationRule(jsonPath = "$.phone", strategy = DesensitizationStrategyEnum.PHONE),
            @DesensitizationRule(jsonPath = "$.detail[*].idCard", strategy = DesensitizationStrategyEnum.ID_CARD),
            @DesensitizationRule(jsonPath = "$.detail[*].bankCard", strategy = DesensitizationStrategyEnum.BANK_CARD, maskChar = '#'),
            @DesensitizationRule(
                    jsonPath = "$[?(@.userType=='VIP')].detail[?(@.address=='武当山金顶1')].address", // 直接使用条件化路径
                    strategy = DesensitizationStrategyEnum.PREFIX_KEEP,
                    prefixKeep = 1
            )
    })
    public UserData getUser(@PathVariable String id) {
        UserData user = new UserData();
        user.setId(id);
        user.setName("张三丰");
        user.setPhone("13812345678");
        user.setEmail("zhangsanfeng@example.com");
        user.setUserType(id.equals("1") ? "VIP" : "NORMAL"); // id=1 是VIP
        user.setIds(123456789);

        UserDetail detail = new UserDetail();
        detail.setIdCard("34012319900101001X");
        detail.setBankCard("6222020100012345678");
        detail.setAddress("武当山金顶");
        UserDetail detail1 = new UserDetail();
        detail1.setIdCard("34012319900101001X1");
        detail1.setBankCard("62220201000123456781");
        detail1.setAddress("武当山金顶1");
        List<UserDetail> list = Arrays.asList(detail, detail1);

        user.setDetail(list);

        return user;
    }

    @GetMapping("/users")
    @Desensitize(rules = {
            @DesensitizationRule(jsonPath = "$[*].name", strategy = DesensitizationStrategyEnum.MIDDLE_MASK, prefixKeep = 1,  suffixKeep = 1)})
    public List<UserData> getUsers() {
        UserData user1 = new UserData();
        user1.setId("1");
        user1.setName("赵敏");
        user1.setPhone("13987654321");
        user1.setEmail("zhaomin@example.com");
        user1.setUserType("VIP");


        UserData user2 = new UserData();
        user2.setId("2");
        user2.setName("周芷若");
        user2.setPhone("13711223344");
        user2.setEmail("zhouzhiruo@example.com");
        user2.setUserType("NORMAL");

        return Arrays.asList(user1, user2);
    }

    @GetMapping("/user/sensitive/{userId}")
    @Desensitize(rules = {
            // 精准脱敏：只脱敏id为 "targetUser" 的用户的手机号
            @DesensitizationRule(jsonPath = "$.data[?(@.id == 'targetUser')].phone", strategy = DesensitizationStrategyEnum.PHONE),
            // 对所有用户的姓名进行脱敏
            @DesensitizationRule(jsonPath = "$.data[*].name", strategy = DesensitizationStrategyEnum.MIDDLE_MASK, prefixKeep = 1, suffixKeep = 1),
            @DesensitizationRule(
                    jsonPath = "$[?(@.userType=='VIP')].email", // 直接使用条件化路径
                    strategy = DesensitizationStrategyEnum.EMAIL
            )     })
    public Map<String, Object> getSpecificUserSensitiveData(@PathVariable String userId) {
        Map<String, Object> response = new HashMap<>();
        UserData userTarget = new UserData();
        userTarget.setId("targetUser");
        userTarget.setName("令狐冲");
        userTarget.setPhone("18800001111");
        userTarget.setEmail("linghuchong@example.com");
        userTarget.setUserType("NORMAL");

        UserData userOther = new UserData();
        userOther.setId("otherUser");
        userOther.setName("任盈盈");
        userOther.setPhone("18822223333");
        userOther.setEmail("renyingying@example.com");
        userOther.setUserType("VIP");

        response.put("data", Arrays.asList(userTarget, userOther));
        response.put("requestUserId", userId);
        return response;
    }

    @GetMapping("/rawstring")
    @Desensitize(rules = {
            @DesensitizationRule(jsonPath = "$", strategy = DesensitizationStrategyEnum.MIDDLE_MASK, prefixKeep = 3, suffixKeep = 3,middleReplaceString="*")
    })
    public String getRawSensitiveString() {
        return "ThisIsAVerySensitiveString12345";
    }


    // --- DTOs ---
    public static class UserData {
        private int ids;
        private String id;
        private String name;
        private String phone;
        private String email;
        private String userType;
        private List<UserDetail> detail;
        // getters and setters
        public String getId() { return id; }
        public void setId(String id) { this.id = id; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        public String getUserType() { return userType; }
        public void setUserType(String userType) { this.userType = userType; }
        public List<UserDetail> getDetail() { return detail; }
        public void setDetail(List<UserDetail> detail) { this.detail = detail; }

        public int getIds() { return ids; }
        public void setIds(int ids) { this.ids = ids; }
    }

    public static class UserDetail {
        private String idCard;
        private String bankCard;
        private String address;
        // getters and setters
        public String getIdCard() { return idCard; }
        public void setIdCard(String idCard) { this.idCard = idCard; }
        public String getBankCard() { return bankCard; }
        public void setBankCard(String bankCard) { this.bankCard = bankCard; }
        public String getAddress() { return address; }
        public void setAddress(String address) { this.address = address; }
    }

    public static class ProductReview {
        private String reviewId;
        private String reviewerName;
        private String comment; // 评论内容，可能包含敏感词或内部编码
        private String internalCode; // 内部编码，例如: ORD-123-ABC-4567

        // Constructor
        public ProductReview(String reviewId, String reviewerName, String comment, String internalCode) {
            this.reviewId = reviewId;
            this.reviewerName = reviewerName;
            this.comment = comment;
            this.internalCode = internalCode;
        }

        // Getters and Setters
        public String getReviewId() { return reviewId; }
        public void setReviewId(String reviewId) { this.reviewId = reviewId; }
        public String getReviewerName() { return reviewerName; }
        public void setReviewerName(String reviewerName) { this.reviewerName = reviewerName; }
        public String getComment() { return comment; }
        public void setComment(String comment) { this.comment = comment; }
        public String getInternalCode() { return internalCode; }
        public void setInternalCode(String internalCode) { this.internalCode = internalCode; }

        @Override
        public String toString() {
            return "ProductReview{" +
                    "reviewId='" + reviewId + '\'' +
                    ", reviewerName='" + reviewerName + '\'' +
                    ", comment='" + comment + '\'' +
                    ", internalCode='" + internalCode + '\'' +
                    '}';
        }
    }

    @GetMapping("/reviews")
    @Desensitize(rules = {
            // 规则1: 对评论内容中的 "秘密" 或 "绝密" (不区分大小写) 进行替换
            @DesensitizationRule(
                    jsonPath = "$[*].comment", // 应用于列表中每个 ProductReview 对象的 comment 字段
                    strategy = DesensitizationStrategyEnum.REGEX_REPLACE,
                    regex = "(?i)(秘密|绝密|confidential)", // (?i)表示不区分大小写
                    replacement = "[已隐藏]"
            ),
            // 规则2: 对评论者姓名进行中间打码 (与之前的例子类似，这里用作对比)
            @DesensitizationRule(
                    jsonPath = "$[*].reviewerName",
                    strategy = DesensitizationStrategyEnum.MIDDLE_MASK,
                    prefixKeep = 1,
                    suffixKeep = 1
            ),
            // 规则3: 对内部编码进行部分隐藏，例如 ORD-123-ABC-4567 -> ORD-***-ABC-####
            @DesensitizationRule(
                    jsonPath = "$[*].internalCode",
                    strategy = DesensitizationStrategyEnum.REGEX_REPLACE,
                    // 正则表达式: (ORD-)\d{3}(-ABC-)\d{4}
                    // 捕获组1: (ORD-) -> $1
                    // 匹配3个数字: \d{3} (这部分会被替换)
                    // 捕获组2: (-ABC-) -> $2
                    // 匹配4个数字: \d{4} (这部分也会被替换)
                    regex = "^(ORD-)\\d{3}(-ABC-)\\d{4}$",
                    replacement = "$1***$2####" // 使用捕获组进行替换
            ),
            // 规则4: 对评论内容中的邮箱地址进行替换 (假设我们不希望暴露邮箱)
            @DesensitizationRule(
                    jsonPath = "$[*].comment", // 再次作用于 comment 字段，规则会按顺序应用
                    strategy = DesensitizationStrategyEnum.REGEX_REPLACE,
                    // 一个相对简单的邮箱匹配正则
                    regex = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}",
                    replacement = "[邮箱已隐藏]"
            )
    })
    public List<ProductReview> getProductReviews() {
        List<ProductReview> reviews = new ArrayList<>();
        reviews.add(new ProductReview(
                "R001",
                "张三丰",
                "这个产品真是太棒了！包含了一些秘密功能。我的邮箱是 testuser@example.com，可以联系我。",
                "ORD-123-ABC-4567"
        ));
        reviews.add(new ProductReview(
                "R002",
                "李莫愁",
                "一般般，有些绝密信息没有披露。CONFIDENTIAL data is here.",
                "ORD-456-ABC-8901"
        ));
        reviews.add(new ProductReview(
                "R003",
                "小龙女",
                "非常好的产品，没有敏感内容。",
                "ORD-789-ABC-1122"
        ));
        return reviews;
    }
    public static class UserActionRequest {
        private String userId;
        private String actionType; // e.g., "VIEW_PROFILE", "UPDATE_SENSITIVE_INFO"
        private String targetField; // e.g., "email", "phone"
        private Map<String, String> additionalParams;

        private String name;

        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }

        // Getters and Setters
        public String getUserId() { return userId; }
        public void setUserId(String userId) { this.userId = userId; }
        public String getActionType() { return actionType; }
        public void setActionType(String actionType) { this.actionType = actionType; }
        public String getTargetField() { return targetField; }
        public void setTargetField(String targetField) { this.targetField = targetField; }
        public Map<String, String> getAdditionalParams() { return additionalParams; }
        public void setAdditionalParams(Map<String, String> additionalParams) { this.additionalParams = additionalParams; }

        @Override
        public String toString() {
            return "UserActionRequest{" +
                    "userId='" + userId + '\'' +
                    ", actionType='" + actionType + '\'' +
                    ", targetField='" + targetField + '\'' +
                    ", additionalParams=" + additionalParams +
                    '}';
        }
    }

    @PostMapping("/user/action")
    @Desensitize(rules = {
            // 规则1: 如果请求体中的 actionType 是 "VIEW_PROFILE"，则对返回结果中特定用户的姓名进行脱敏
            @DesensitizationRule(
                    jsonPath = "$.data[*].email", // #body.userId 引用请求体中的 userId
                    strategy = DesensitizationStrategyEnum.MIDDLE_MASK, prefixKeep = 2, suffixKeep = 2
                    //conditionJsonPath = "#body.actionType", // 条件基于请求体中的 actionType
                    //conditionValue = "'VIEW_PROFILE'"     // 注意字符串字面量的引号
            ),
            // 规则2: 如果请求体中的 actionType 是 "UPDATE_SENSITIVE_INFO"
            // 并且 targetField 是 "email"，则对该用户的 email 进行脱敏
       /*     @DesensitizationRule(
                    jsonPath = "$.data[?(@.id == #body.userId)].email",
                    strategy = DesensitizationStrategyEnum.EMAIL
                  //  conditionJsonPath = "#body.actionType",
                   // conditionValue = "'UPDATE_SENSITIVE_INFO'"
                    // 这里还可以链式AND条件，但目前框架的 isConditionMet 是一对一的 conditionPath-conditionValue
                    // 如果需要更复杂的AND/OR条件，可能需要isConditionMet支持SpEL表达式或者多个conditionRule
            ),*/
            // 规则2.1: 如果请求体中的 actionType 是 "UPDATE_SENSITIVE_INFO"
            // 并且 targetField 是 "phone"，则对该用户的 phone 进行脱敏
            // (为了演示，我们假设 targetField 的判断在外部或通过多个规则实现)
            // 此处我们用一个独立的规则，并通过 conditionValue 的动态性来模拟一部分
       /*     @DesensitizationRule(
                    jsonPath = "$.data[?(@.id == #body.userId)].phone",
                    strategy = DesensitizationStrategyEnum.PHONE
                    //conditionJsonPath = "#body.targetField", // 条件基于请求体中的 targetField
                   // conditionValue = "'phone'" // 只有当 targetField 是 'phone' 时此规则的条件才满足
                    // 并且 actionType 也需要是 UPDATE_SENSITIVE_INFO (通过另一个规则或组合逻辑)
            ),*/
            // 规则3: 使用请求体中 additionalParams 的值来动态构建JsonPath的一部分
            // 例如，如果 additionalParams.get("filterKey") 是 "status", jsonPath会变成 $.auditLog[?(@.status == 'PENDING')].details
            // (这个例子需要JsonPath支持更复杂的动态路径构建，或者在 replacePlaceholders 中有更强的SpEL能力)
            // 当前的 #body.additionalParams.filterKey 应该能工作
       /*     @DesensitizationRule(
                    jsonPath = "$.auditLog[?(@.#body.additionalParams.filterKey == #body.additionalParams.filterValue)].details",
                    strategy = DesensitizationStrategyEnum.REGEX_REPLACE, regex=".*", replacement = "[FILTERED]"
            )*/
    })
    public Map<String, Object> performUserAction(@RequestBody UserActionRequest request,
                                                 @RequestParam(defaultValue = "defaultContext") String operationContext) {

        Map<String, Object> response = new HashMap<>();
        List<UserData> users = new ArrayList<>();

        // 模拟一些用户数据
        UserData user1 = new UserData();
        user1.setId("defaultContext");
        user1.setName("令狐冲");
        user1.setPhone("18800001111");
        user1.setEmail("linghuchong.vip@example.com");
        user1.setUserType("VIP");
        users.add(user1);

        UserData user2 = new UserData();
        user2.setId("user456");
        user2.setName("任盈盈");
        user2.setPhone("18822223333");
        user2.setEmail("renyingying.normal@example.com");
        user2.setUserType("NORMAL_USER");
        users.add(user2);

        response.put("data", users);
        response.put("operationContext", operationContext);
        response.put("status", "SUCCESS");

        // 模拟审计日志数据，用于规则3的演示
        List<Map<String, String>> auditLogs = new ArrayList<>();
        Map<String, String> log1 = new HashMap<>();
        log1.put("action", "LOGIN");
        log1.put("status", "SUCCESS"); // 假设这个是 additionalParams.filterKey 指向的字段
        log1.put("details", "User user123 logged in successfully.");
        auditLogs.add(log1);

        Map<String, String> log2 = new HashMap<>();
        log2.put("action", "UPDATE_PROFILE");
        log2.put("status", "PENDING"); // 假设这个是 additionalParams.filterValue 期望的值
        log2.put("details", "Profile update for user456 is pending approval.");
        auditLogs.add(log2);
        response.put("auditLog", auditLogs);


        // 在这里，脱敏框架会根据 UserActionRequest 的内容和 @Desensitize 规则
        // 来决定如何处理 'response' 对象中的数据。

        return response;
    }
}
